#ifndef cathlibcpp_utility_H
#define cathlibcpp_utility_H

// File:       utility.h
// Author:     (c) Miles Sabin, 1996
// Purpose:    ANSI C++ pair template class and comparator function templates


#ifndef cathlibcpp_bool_H
#include "bool.h"
#endif

#ifndef cathlibcpp_config_H
#include "config.h"
#endif


// operators

template<class T>
inline bool operator!=(T const& lhs, T const& rhs);

template<class T>
inline bool operator> (T const& lhs, T const& rhs);

template<class T>
inline bool operator<=(T const& lhs, T const& rhs);

template<class T>
inline bool operator>=(T const& lhs, T const& rhs);


// pairs

template<class T1, class T2>
struct pair
{
  // constructors
  pair()
    : first(T1()),                // CFront causes problems here if T1 or T2
      second(T2())                // are const types and there is no initializer
    {}

  inline pair(T1 const& a, T2 const& b)
    : first(a),
      second(b)
    {}

  inline ~pair() {}

  // data members
  T1 first;
  T2 second;
};


template<class T1, class T2>
inline bool operator==(pair<T1, T2> const& x, pair<T1, T2> const& y);

template<class T1, class T2>
inline bool operator<(pair<T1, T2> const& x, pair<T1, T2> const& y);

template<class T1, class T2>
inline pair<T1, T2> make_pair(T1 const& x, T2 const& y);


// Implementation of operators

template<class T>
inline bool operator!=(T const& lhs, T const& rhs)
{
  return !(lhs == rhs);
}

template<class T>
inline bool operator> (T const& lhs, T const& rhs)
{
  return rhs < lhs;
}

template<class T>
inline bool operator<=(T const& lhs, T const& rhs)
{
  return !(rhs < lhs);
}

template<class T>
inline bool operator>=(T const& lhs, T const& rhs)
{
  return !(lhs < rhs);
}


// Implementation of pair<T1, T2> free fns

template<class T1, class T2>
inline bool operator==(pair<T1, T2> const& x, pair<T1, T2> const& y)
{
  return x.first == y.first && x.second == y.second;
}

template<class T1, class T2>
inline bool operator< (pair<T1, T2> const& x, pair<T1, T2> const& y)
{
  return x.first < y.first || (!(y.first < x.first) && x.second < y.second);
}

template<class T1, class T2>
inline pair<T1, T2> make_pair(T1 const& x, T2 const& y)
{
  return pair<T1, T2>(x, y);
}

#endif
